<?php
/**
 * Class to create model list in backend
 * @author muinx
 */
class CreateBackendModelList
{
	protected $model;
	
	function __construct($model)
	{
		$this->model = $model;
	}
	
	/**
	 * Process model content
	 * @param String $content		Content to process
	 * @param String $filename		File name
	 * @param Object $component		Component Object
	 * @return String	Content was replaced
	 */
	function create($content, $filename, $component)
	{
		$model = $this->model;
		
		$comName = str_replace(' ', '_', strtolower($component->name));
		$componentPrefix = str_replace(' ', '_', ucwords($component->name));
		
		$modelFormName 	= null;
		$search 		= array();
		$replace 		= array();
		
		if(is_object($model))
			$modelFormName = str_replace(' ', '_', strtolower($model->name));
		
		$search = array('#table#', '#xs#', '#author#', '#to_copy#', '#component_prefix#', '#X_with_s#', '#TO_COPY#', '#XS#', '#X_no_s#');
		$replace = array($model->table_name, $filename, $component->author, $comName, $componentPrefix, ucfirst($filename), strtoupper($comName), strtoupper($filename), ucfirst($modelFormName));

		$joins = GenerateHelper::getRecord('#__gencode_genm_join', null, 'genm_id = ' . (int) $model->id);
		
		require_once JPATH_COMPONENT_ADMINISTRATOR . DS . 'models' . DS . 'genm.php';
		
		//select fields
		$genmFields = $this->getFieldSelected($model->id, null, $model->table_name);
		
		$search[] = '#SELECT_FIELDS#';
		$replace[] = ', ' .$genmFields;
		
		$genmFieldsConfig = $this->getFieldSelected($model->id, true, $model->table_name);
		
		$search[] = '#SELECT_FIELDS_CONFIG#';
		$replace[] = $genmFieldsConfig;
		
		$strJoin = '';
		
		foreach ($joins as $key => $join)
		{
			$joinTable = $join->join_table;
			$tableAlias = $joinTable.'_'.$key;
			
			$strJoin .= '// Join over the ' . $joinTable . "\n";
			
			$listField = array();
			$fields = explode(',', str_replace(' ', '', $join->join_table_fields));
			
			if(!empty($fields))
			{
				foreach ($fields as $field)
				{
					if($field)
						$listField[] = $tableAlias . '.' . $field . ' AS ' . $tableAlias . '_' . $field;
				}
			}
			
			if(!empty($listField))
			{
				$listField = implode(', ', $listField);
				$strJoin .= '$query->select(\''.$listField.'\');' . "\n";
			}
			
			$strJoin .= '$query->join(\''.$join->join_type.'\', \'#__'.$joinTable.' AS '.$tableAlias.
										' ON '.$tableAlias.'.'.$join->join_field_on_1.' = #__'.$join->join_table_on_2.'.'.$join->join_field_on_2.'\');' . "\n\n";
		}
		
		$search[] = '#JOIN_TABLE_STRING#';
		$replace[] = $strJoin;
		
		//get filter
		$filter = unserialize($model->fields_to_filter);
		
		$strFilter = '';
		
		/**
		 * Set filter
		 */
		if(isset($filter['state']))
		{
			$strFilter .= '// Filter by published state
							$published = $this->getState(\'filter.state\');
							if (is_numeric($published)) {
								$query->where(\'#__'.$model->table_name.'.state = \'.(int) $published);
							} else if ($published === \'\') {
								$query->where(\'(#__'.$model->table_name.'.state IN (0, 1))\');
							}
						';
			
			$search[] = '#SET_FILTER_STATE_STATE#';
			$replace[] = '$state = $this->getUserStateFromRequest($this->context.\'.filter.state\', \'filter_state\', \'\', \'string\');
							$this->setState(\'filter.state\', $state);';
		}
		
		if(isset($filter['category']))
		{
			$strFilter .= '// Filter by category.
							$categoryId = $this->getState(\'filter.category_id\');
							if (is_numeric($categoryId)) {
								$query->where(\'#__'.$model->table_name.'.'.$filter['catid'].' = \'.(int) $categoryId);
							}
						';
			
			$search[] = '#SET_FILTER_STATE_CATEGORY#';
			$replace[] = '$categoryId = $this->getUserStateFromRequest($this->context.\'.filter.category_id\', \'filter_category_id\', \'\');
							$this->setState(\'filter.category_id\', $categoryId);';
			
			$search[] = '#FUNCTION_CATEGORY_ORDERS#';
			$replace[] = $this->getFunctionCategoryOrders($filename, $filter['catid']);
		}
		else 
		{
			$search[] = '#SET_FILTER_STATE_CATEGORY#';
			$replace[] = null;
			
			$search[] = '#FUNCTION_CATEGORY_ORDERS#';
			$replace[] = null;
		}
		
		if(isset($filter['language']))
		{
			$strFilter .= '// Filter by language.
							if ($language = $this->getState(\'filter.language\')) {
								$query->where(\'#__'.$model->table_name.'.'.$filter['language_id'].' = \'.$db->quote($language));
							}
						';
			
			$search[] = '#SET_FILTER_STATE_LANGUAGE#';
			$replace[] = '$language = $this->getUserStateFromRequest($this->context.\'.filter.language\', \'filter_language\', \'\');
							$this->setState(\'filter.language\', $language);';
		}
		else 
		{
			$search[] = '#SET_FILTER_STATE_LANGUAGE#';
			$replace[] = null;
		}
		
		if(isset($filter['created_by']))
		{
			$functionGetAuthor = $this->getFunctionAuthor($filename);
			
			$search[] = '#FUNCTION_GET_AUTHOR#';
			$replace[] = $functionGetAuthor;
			
			$strFilter .= '// Filter by author
							$authorId = $this->getState(\'filter.author_id\');
							if (is_numeric($authorId)) {
								$type = $this->getState(\'filter.author_id.include\', true) ? \'= \' : \'<>\';
								$query->where(\'#__'.$model->table_name.'.created_by \'.$type.(int) $authorId);
							}';
			
			$search[] = '#SET_FILTER_STATE_AUTHOR#';
			$replace[] = '$authorId = $app->getUserStateFromRequest($this->context.\'.filter.author_id\', \'filter_author_id\');
							$this->setState(\'filter.author_id\', $authorId);';
		}
		else 
		{
			$search[] = '#SET_FILTER_STATE_AUTHOR#';
			$replace[] = null;
		}
		
		//var_dump($filter);
		
		$search[] = '#FILTER#';
		$replace[] = $strFilter;
		
		//search
		$strSearch = '';
		$arrConditionSearch = array();
		
		$fieldSearch = explode(',', str_replace(' ', '', $model->fields_to_search));
		
		/**
		 * Set field to search
		 */
		if(!empty($fieldSearch))
		{
			$strSearch .= '// Filter by search
						$search = $this->getState(\'filter.search\');
						if (!empty($search))
						{							
							$searchLike = $db->Quote(\'%\'.$db->getEscaped($search, true).\'%\');
							$search = $db->Quote($db->getEscaped($search, true));
						';
			
			foreach ($fieldSearch as $f_Search)
			{
				$operator = ($f_Search[0] == '*') ? ' LIKE ' : ' = ';
				
				if($f_Search[0] == '*')
				{
					$f_Search = str_replace('*', '', $f_Search);
					$arrConditionSearch[] = '#__'.$model->table_name.'.'.$f_Search.$operator.'\'.$searchLike.\'';
				}
				else 
				{
					$arrConditionSearch[] = '#__'.$model->table_name.'.'.$f_Search.$operator.'\'.$search.\'';
				}
				
			}
			
			if(!empty($arrConditionSearch))
				$strSearch .= '$query->where(\'('.implode(' OR ', $arrConditionSearch).')\');';
				
			$strSearch .= '
							} //end search';
			
			$search[] = '#SET_FILTER_STATE_SEARCH#';
			$replace[] = '$search = $this->getUserStateFromRequest($this->context.\'.filter.search\', \'filter_search\');
							$this->setState(\'filter.search\', $search);';
		}
		else 
		{
			$search[] = '#SET_FILTER_STATE_SEARCH#';
			$replace[] = null;
		}
		
		$search[] = '#SEARCH#';
		$replace[] = $strSearch;
		
		$content = str_replace($search, $replace, $content);
		
		return $content;
	}
	
	/**
	 * Get fields in model
	 * @param Int $modelId				Model ID
	 * @param Bool $getConfig			If true, will set field for config
	 * @param String $modelTableName	Table name that model selected
	 * @return	List fields
	 */
	public function getFieldSelected($modelId, $getConfig = null, $modelTableName = null)
	{
		$db = JFactory::getDbo();
		$query = "SELECT field FROM #__gencode_genm_fields WHERE genm_id = '$modelId'";
		
		$db->setQuery($query);
		$rs = $db->loadResultArray();
		
		$fields = array();
		
		if($getConfig)
		{
			foreach ($rs as $rec)
				$fields[] = "'" . $rec . "', " . "'#__".$modelTableName."." . $rec . "'";
		}
		else 
		{
			foreach ($rs as $rec)
				$fields[] = "#__".$modelTableName."." . $rec . "";
		}
		
		$fields = implode(', ', $fields);
		
		return $fields;
	}
	
	/**
	 * Fucntion template
	 * @param String $filename	Filename (Table name)
	 */
	private function getFunctionAuthor($filename)
	{
		$functionGetAuthor = '/**
			 * Build a list of authors
			 *
			 * @return	JDatabaseQuery
			 * @since	1.6
			 */
			public function getAuthors() {
				// Create a new query object.
				$db = $this->getDbo();
				$query = $db->getQuery(true);
		
				// Construct the query
				$query->select(\'u.id AS value, u.name AS text\');
				$query->from(\'#__users AS u\');
				$query->join(\'INNER\', \'#__'.$filename.' AS c ON c.created_by = u.id\');
				$query->group(\'u.id\');
				$query->order(\'u.name\');
		
				// Setup the query
				$db->setQuery($query->__toString());
		
				// Return the result
				return $db->loadObjectList();
			}';

		return $functionGetAuthor;
	}
	
	/**
	 * Function template
	 * @param String $filename		Table name
	 * @param String $fieldCatID	Field category id in table
	 */
	private function getFunctionCategoryOrders($filename, $fieldCatID)
	{
		$str = '/**
			 * Method to get the maximum ordering value for each category.
			 *
			 * @since	1.6
			 */
			function &getCategoryOrders()
			{
				if (!isset($this->cache[\'categoryorders\'])) {
					$db		= $this->getDbo();
					$query	= $db->getQuery(true);
					$query->select(\'MAX(ordering) as `max`, '.$fieldCatID.'\');
					$query->from(\'#__'.$filename.'\');
					$query->group(\''.$fieldCatID.'\');
					$db->setQuery($query);
					$this->cache[\'categoryorders\'] = $db->loadAssocList(\''.$fieldCatID.'\', 0);
				}
				return $this->cache[\'categoryorders\'];
			}';
		
		return $str;
	}
}